package com.hkts.naturalgasauthentication.base.controller;

import cn.hutool.core.util.StrUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hkts.management.common.utils.Result;
import com.hkts.management.common.utils.ResultUtil;
import com.hkts.management.common.utils.SnowFlakeUtil;
import com.hkts.naturalgasauthentication.base.entity.Permission;
import com.hkts.naturalgasauthentication.base.entity.RolePermission;
import com.hkts.naturalgasauthentication.base.entity.User;
import com.hkts.naturalgasauthentication.base.service.PermissionService;
import com.hkts.naturalgasauthentication.base.service.RolePermissionService;
import com.hkts.naturalgasauthentication.base.service.mybatis.IPermissionService;
import com.hkts.naturalgasauthentication.common.constant.CommonConstant;
import com.hkts.naturalgasauthentication.common.redis.RedisTemplateHelper;
import com.hkts.naturalgasauthentication.common.vo.MenuVo;
import com.hkts.naturalgasauthentication.config.permission.MySecurityMetadataSource;
import com.hkts.naturalgasauthentication.utils.CustomStringUtils;
import com.hkts.naturalgasauthentication.utils.SecurityUtil;
import com.hkts.naturalgasauthentication.utils.VoUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author Exrick
 */
@Slf4j
@RestController
@RequestMapping("/authentication/permission")
@CacheConfig(cacheNames = "permission")
@Transactional
public class PermissionController {

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private IPermissionService iPermissionService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private RedisTemplateHelper redisTemplateHelper;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private MySecurityMetadataSource mySecurityMetadataSource;

    /**
     * 获取用户页面菜单数据
     * @return
     */
    @RequestMapping(value = "/getMenuList", method = RequestMethod.GET)
    public Result<List<MenuVo>> getAllMenuList(){


        // 读取缓存
        User u = securityUtil.getCurrUser();
        /*String key = "permission::userMenuList:" + u.getId();
        String v = redisTemplate.opsForValue().get(key);
        if(StrUtil.isNotBlank(v)){
            menuList = new Gson().fromJson(v, new TypeToken<List<MenuVo>>(){}.getType());
            return new ResultUtil<List<MenuVo>>().setData(menuList);
        }*/


        // 用户所有权限 已排序去重

        if (u.getNickName().equals("admin")){
            List<Permission> all = permissionService.findAll();
            return new ResultUtil<List<MenuVo>>().setData(getMenuList(all));
        }else {
            List<Permission> list = iPermissionService.findByUserId(u.getId());
            return new ResultUtil<List<MenuVo>>().setData(getMenuList(list));
        }

        // 缓存
        /*redisTemplate.opsForValue().set(key, new Gson().toJson(menuList), 15L, TimeUnit.DAYS);*/

    }

    public List<MenuVo> getMenuList(List<Permission> list){
        List<MenuVo> menuList = new ArrayList<>();
        // 筛选0级页面
        for(Permission p : list){
            if(CommonConstant.PERMISSION_NAV.equals(p.getType())&&CommonConstant.LEVEL_ZERO.equals(p.getLevel())){
                menuList.add(VoUtil.permissionToMenuVo(p));
            }
        }
        // 筛选一级页面
        List<MenuVo> firstMenuList = new ArrayList<>();
        for(Permission p : list){
            if(CommonConstant.PERMISSION_PAGE.equals(p.getType())&&CommonConstant.LEVEL_ONE.equals(p.getLevel())){
                firstMenuList.add(VoUtil.permissionToMenuVo(p));
            }
        }
        // 筛选二级页面
        List<MenuVo> secondMenuList = new ArrayList<>();
        for(Permission p : list){
            if(CommonConstant.PERMISSION_PAGE.equals(p.getType())&&CommonConstant.LEVEL_TWO.equals(p.getLevel())){
                secondMenuList.add(VoUtil.permissionToMenuVo(p));
            }
        }
        // 筛选二级页面拥有的按钮权限
        List<MenuVo> buttonPermissions = new ArrayList<>();
        for(Permission p : list){
            if(CommonConstant.PERMISSION_OPERATION.equals(p.getType())&&CommonConstant.LEVEL_THREE.equals(p.getLevel())){
                buttonPermissions.add(VoUtil.permissionToMenuVo(p));
            }
        }

        // 匹配二级页面拥有权限
        for(MenuVo m : secondMenuList){
            List<String> permTypes = new ArrayList<>();
            for(MenuVo me : buttonPermissions){
                if(m.getId().equals(me.getParentId())){
                    permTypes.add(me.getButtonType());
                }
            }
            m.setPermTypes(permTypes);
        }
        // 匹配一级页面拥有二级页面
        for(MenuVo m : firstMenuList){
            List<MenuVo> secondMenu = new ArrayList<>();
            for(MenuVo me : secondMenuList){
                if(m.getId().equals(me.getParentId())){
                    secondMenu.add(me);
                }
            }
            m.setChildren(secondMenu);
        }
        // 匹配0级页面拥有一级页面
        for(MenuVo m : menuList){
            List<MenuVo> firstMenu = new ArrayList<>();
            for(MenuVo me : firstMenuList){
                if(m.getId().equals(me.getParentId())){
                    firstMenu.add(me);
                }
            }
            m.setChildren(firstMenu);
        }

        return menuList;
    }
    /**
     * 获取权限菜单树
     * @return
     */
    @RequestMapping(value = "/getAllList", method = RequestMethod.GET)
    //@Cacheable(key = "'allList'")
    public Result<List<Permission>> getAllList(){
        // 0级
        List<Permission> listData = new ArrayList<Permission>();
        List<Permission> list = permissionService.findFirstLevel();
        for (Permission permission : list) {
             if(!CustomStringUtils.isNotBlank(permission.getParentId())){
                 List<Permission> permissions = childrenPerssion(permission);
                 permission.setChildren(permissions);
                 listData.add(permission);
            }
        }

        return new ResultUtil<List<Permission>>().setData(listData);
    }
        public  List<Permission> childrenPerssion(Permission permission){
            List<Permission> byParentIdOrderBySortOrder = permissionService.findByParentId(permission.getId());
            Permission byid = permissionService.findByid(permission.getId());
            for(int i=0;i<byParentIdOrderBySortOrder.size();i++){
                List<Permission> permissions = childrenPerssion(byParentIdOrderBySortOrder.get(i));
                byParentIdOrderBySortOrder.get(i).setChildren(permissions);
                byParentIdOrderBySortOrder.get(i).setPrentName(byid.getTitle());

            }
        return byParentIdOrderBySortOrder;
    }

    /**
     * 添加
     * @param permission
     * @return
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @CacheEvict(key = "'menuList'")
    public Result<Permission> add(Permission permission){

        // 判断拦截请求的操作权限按钮名是否已存在
        if(CommonConstant.PERMISSION_OPERATION.equals(permission.getType())){
            List<Permission> list = permissionService.findByTitle(permission.getTitle());
            if(list!=null&&list.size()>0){
                return new ResultUtil<Permission>().setErrorMsg("名称已存在");
            }
        }

        if (StringUtils.isNotBlank(permission.getParentId())){
            Permission permission1 = permissionService.get(permission.getParentId());
            permission.setLevel(permission1.getLevel() + 1);
            permission.setType(0);
        }else {
            permission.setLevel(0);
            permission.setType(-1);
        }

        permission.setId(String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()));
        Permission u = permissionService.save(permission);
        //重新加载权限
        mySecurityMetadataSource.loadResourceDefine();
        //手动删除缓存
        redisTemplate.delete("permission::allList");
        return new ResultUtil<Permission>().setData(u);
    }

    /**
     * 编辑
     * @param permission
     * @return
     */
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public Result<Permission> edit(Permission permission){


        // 判断拦截请求的操作权限按钮名是否已存在
        if(CommonConstant.PERMISSION_OPERATION.equals(permission.getType())){
            // 若名称修改
            Permission p = permissionService.get(permission.getId());
            if(!p.getTitle().equals(permission.getTitle())){
                List<Permission> list = permissionService.findByTitle(permission.getTitle());
                if(list!=null&&list.size()>0){
                    return new ResultUtil<Permission>().setErrorMsg("名称已存在");
                }
            }
        }
        if (permission.getId() != null){
            Permission permission1 = permissionService.get(permission.getId());
            permission.setCreateTime(permission1.getCreateTime());
            permission.setType(permission1.getType());
            permission.setLevel(permission1.getLevel());
            Permission u = permissionService.update(permission);
            /*mySecurityMetadataSource.loadResourceDefine();
            //手动批量删除缓存
            Set<String> keys = redisTemplateHelper.keys("userPermission:" + "*");
            redisTemplate.delete(keys);
            Set<String> keysUser = redisTemplateHelper.keys("user:" + "*");
            redisTemplate.delete(keysUser);
            Set<String> keysUserMenu = redisTemplateHelper.keys("permission::userMenuList:*");
            redisTemplate.delete(keysUserMenu);
            redisTemplate.delete("permission::allList");*/
            return new ResultUtil<Permission>().setData(u);
        }else {
            return ResultUtil.error("该权限不存在");
        }
        /*Permission u = permissionService.update(permission);
        //重新加载权限
        mySecurityMetadataSource.loadResourceDefine();
        //手动批量删除缓存
        Set<String> keys = redisTemplateHelper.keys("userPermission:" + "*");
        redisTemplate.delete(keys);
        Set<String> keysUser = redisTemplateHelper.keys("user:" + "*");
        redisTemplate.delete(keysUser);
        Set<String> keysUserMenu = redisTemplateHelper.keys("permission::userMenuList:*");
        redisTemplate.delete(keysUserMenu);
        redisTemplate.delete("permission::allList");
        return new ResultUtil<Permission>().setData(u);*/

    }

    /**
     * 批量通过id删除
     * @param ids
     * @return
     */
    @RequestMapping(value = "/delByIds/{ids}", method = RequestMethod.DELETE)
    @CacheEvict(key = "'menuList'")
    public Result<Object> delByIds(@PathVariable String[] ids){

        for(String id:ids){
            List<RolePermission> list = rolePermissionService.findByPermissionId(id);
            if(list!=null&&list.size()>0){
                return ResultUtil.error("删除失败，包含正被角色使用关联的菜单或权限");
            }
        }
        for(String id:ids){
            permissionService.delete(id);
        }
        //重新加载权限
        mySecurityMetadataSource.loadResourceDefine();
        //手动删除缓存
        redisTemplate.delete("permission::allList");
        return ResultUtil.success("批量通过id删除数据成功");
    }

    /**
     * 搜索菜单
     * @param title
     * @return
     */
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public Result<List<Permission>> searchPermissionList(@RequestParam String title){

        List<Permission> list = permissionService.findByTitleLikeOrderBySortOrder("%"+title+"%");
        return new ResultUtil<List<Permission>>().setData(list);
    }
}
